﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Reflection;
using SubSonic;

namespace ExtraClub.Domain.Forms {
    public static class FieldType {
        public const string Email = "email";
        public const string String = "string";
        public const string Text = "text";
        public const string Select = "select";
        public const string Number = "number";
        public const string Birthdate = "birthdate";
        public const string Integer = "integer";
        public const string Combined = "combine";
        public const string Group = "group";
        public const string Hidden = "hidden";
        public const string Html = "html";
        public const string Boolean = "boolean";
        public const string Date = "date";
        public const string DateSplit = "datesplit";
    }
    public class FieldCollection : List<string> {
        public BaseUserControl Control { get; set; }
        public string LabelKeySuffex { get; set; }

        public string JSON() {
            StringBuilder sb = new StringBuilder();
            this.ForEach(delegate(string item) {
                if (sb.Length > 0) {
                    sb.Append(",");
                }
                sb.Append(item);
            });
            sb.Insert(0, "[");
            sb.Append("]");
            return sb.ToString();
        }
    }
    [DataContractAttribute, KnownTypeAttribute(typeof(Field))]
    public class Field {
        #region Public Not Serilizable Properties
        public string Label { get { return inputParams.label; } set { inputParams.label = value; } }
        public string RightLabel { get { return inputParams.rightLabel; } set { inputParams.rightLabel = value; } }
        public string Description { get { return inputParams.description; } set { inputParams.description = value; } }
        public string Legend { get { return inputParams.legend; } set { inputParams.legend = value; } }
        public string CodeName { get { return inputParams.name; } set { inputParams.name = value; } }
        public string DateFormat { get { return inputParams.dateFormat; } set { inputParams.dateFormat = value; } }
        public string Value { get { return inputParams.value; } set { inputParams.value = value; } }
        public int Size { get { return inputParams.size; } set { inputParams.size = value; } }
        public bool Negativ { get { return inputParams.negative; } set { inputParams.negative = value; } }
        public int MinLength { get { return inputParams.minLength; } set { inputParams.minLength = value; } }
        public string[] SelectOptions { get { return inputParams.selectOptions; } set { inputParams.selectOptions = value; } }
        public string[] SelectValues { get { return inputParams.selectValues; } set { inputParams.selectValues = value; } }
        public string TypeInvite { get { return inputParams.typeInvite; } set { inputParams.typeInvite = value; } }
        public int Rows { get { return inputParams.rows; } set { inputParams.rows = value; } }
        public int Cols { get { return inputParams.cols; } set { inputParams.cols = value; } }
        public bool Readonly { get { return inputParams.Readonly; } set { inputParams.Readonly = value; } }
        public bool Required { get { return inputParams.required; } set { inputParams.required = value; } }
        public string[] Separators { get { return inputParams.separators; } set { inputParams.separators = value; } }
        public Field[] Fields { get { return inputParams.fields; } set { inputParams.fields = value; } }
        #endregion

        [DataMember]
        private string type { get; set; }

        [DataMember]
        private FieldInputParams inputParams { get; set; }

        [DataContractAttribute]
        public class FieldInputParams {
            [DataMember(EmitDefaultValue = false)]
            public string label { get; set; }

            [DataMember(EmitDefaultValue = false)]
            public string rightLabel { get; set; }

            [DataMember(EmitDefaultValue = false)]
            public string description { get; set; }

            [DataMember(EmitDefaultValue = false)]
            public string legend { get; set; }

            [DataMember(EmitDefaultValue = false)]
            public string name { get; set; }

            [DataMember(EmitDefaultValue = false)]
            public string value { get; set; }

            [DataMember(EmitDefaultValue = false)]
            public string dateFormat { get; set; }

            [DataMember(EmitDefaultValue = false)]
            public int size { get; set; }

            [DataMember(EmitDefaultValue = false)]
            public int minLength { get; set; }

            [DataMember(EmitDefaultValue = false)]
            public string[] selectOptions { get; set; }

            [DataMember(EmitDefaultValue = false)]
            public string[] selectValues { get; set; }

            [DataMember(EmitDefaultValue = false)]
            public string[] separators { get; set; }

            [DataMember(EmitDefaultValue = false)]
            public bool negative { get; set; }

            [DataMember(EmitDefaultValue = false)]
            public string typeInvite { get; set; }

            [DataMember(EmitDefaultValue = false)]
            public int rows { get; set; }

            [DataMember(EmitDefaultValue = false)]
            public int cols { get; set; }

            [DataMember(Name = "readonly", EmitDefaultValue = false)]
            public bool Readonly { get; set; }

            [DataMember(EmitDefaultValue = false)]
            public bool required { get; set; }

            [DataMember(EmitDefaultValue = false)]
            public Field[] fields { get; set; }
        }
        public string LabelKeySuffex { get; set; }

        public Field(string type, string codeName, Action<Field> action, FieldCollection fs)
            : this(type, codeName, action, fs, true) {
        }
        public Field(string type, string codeName, Action<Field> action, FieldCollection fs, bool addToCollection) {
            inputParams = new FieldInputParams();

            this.type = type;

            if (codeName != null) {
                this.CodeName = codeName.ToLower();
            }

            if (fs != null && fs.Control != null && this.CodeName != null) {
                LabelKeySuffex = this.CodeName + fs.LabelKeySuffex;
                this.Label = fs.Control.UIText[LabelKeySuffex];
            }

            action(this);

            if (fs != null && addToCollection) {
                fs.Add(this.ToJSON());
            }
        }
    }
}
